<?php

/**
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 3 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 */
/**
 * Shopping cart item abstract class
 * @package Util
 * @author Vincze Tamás pilou@pilou.hu
 * @version 0.3.1
 */

namespace Util\Cart;

abstract class ACartItem implements ICartItem {

	/**
	 * The unique identifier of the item
	 * @access protected
	 * @final
	 * @var mixed
	 */
	protected $_id;
	
	/**
	 * Name of the cart item
	 * @access protected
	 * @final
	 * @var string
	 */
	protected $_name;
	
	/**
	 * Net price of the cart item
	 * @access protected
	 * @final
	 * @var float
	 */
	protected $_netPrice;
	
	/**
	 * Vat of the price item
	 * @access protected
	 * @final
	 * @var float
	 */
	protected $_vat;
	
	/**
	 * Quantity of the item
	 * @access protected
	 * @var int
	 */
	protected $_qty;
	
	/**
	 * Misc informations of the item (productID for example)
	 * @access protected
	 * @final
	 * @var mixed
	 */
	protected $_misc;
	
	/**
	 * Is quantity modifiable (should be hard coded)
	 * @access protected
	 * @var bool
	 */
	protected $_qtyModifiable;
	
	/**
	 * If true price is added to the sum price of the cart items, if false price is substracted from the sum price of the Cart (should be hard coded)
	 * @access protected
	 * @var bool
	 */
	protected $_addsOrSubsPrice;
	
	/**
	 * If true other items can subtract from this item's price too from the sum price, if false it can never be subsctracted from the sum price of the Cart (should be hard coded)
	 * @access protected
	 * @var bool
	 */
	protected $_canBeSubstracted;
	
	/**
	 * Sets the item data
	 * @access protected
	 * @final
	 * @var mixed $id
	 * @var string $name
	 * @var float $netPrice
	 * @var float $vat
	 * @var int $qty
	 * @var mixed $misc
	 */
	protected function __construct($options){
        foreach ($options as $var => $value) {
            $this->{"_".$var} = $value;
        }
        $this->_netPrice = abs($this->_netPrice);
        if ($this->_vat < 0 || $this->_vat >= 100){
            throw new \Exception("Vat must be between 0 and 100 or 0");
        }
	}	

	/**
	 * Gets the name of the item
	 * @access public
	 * @final
	 * @return string
	 */
	public final function getName(){
		return $this->_name;
	}

	/**
	 * Gets the unique identifier of the item
	 * @access public
	 * @var bool $idOnly get the value only of the $_id var if true otherwise the called class name too (It's tottalí unique then)
	 * @return string
	 */
	public function getID($idOnly = true) {
		if ($idOnly) {
			return $this->_id;
		}
		return $this->_id . $this->getClass(true);
	}

	/**
	 * Gets the class of the item beacuse instanceof is not working in template engines
	 * @access public
	 * @var bool $nameSpace default: false gets the full class name (with namespace or not)
	 * @return string
	 */
	public function getClass($nameSpace = false) {
		$class = get_called_class();
		if ($nameSpace) {
			return $class;
		}
		$explode = explode("\\", $class);
		return end($explode);
	}
	
	/**
	 * Gets the net price of the item
	 * @access public
	 * @return float
	 */
	public function getNetPrice(){
		if ($this->_addsOrSubsPrice === false){
			return 0-$this->_netPrice;
		}	
		return $this->_netPrice;
	}

	/**
	 * Gets the vat of the item
	 * @access public
	 * @final
	 * @return float
	 */
	public final function getVat(){
		return $this->_vat;
	}
	
	/**
	 * Gets the vat price of the item
	 * @access public
	 * @final
	 * @return float
	 */
	public final function getVatPrice(){
		return $this->getNetPrice() * $this->getVat() / 100;
	}


	/**
	 * Gets the gross price of the item
	 * @access public
	 * @final
	 * @return float
	 */
	public final function getGrossPrice(){
		return $this->getNetPrice() + $this->getVatPrice();
	}

	/**
	 * Gets quantity of the item
	 * @access public
	 * @final
	 * @return string
	 */
	public final function getQty(){
		return $this->_qty;
	}
	
	/**
	 * Gets the sum net price of the item (netPrice * qty)
	 * @access public
	 * @final
	 * @return float
	 */
	public final function getNetSum(){
		return $this->getPrice() * $this->getQty();
	}
	
	/**
	 * Gets the sum gross price of the item (grossPrice * qty)
	 * @access public
	 * @final
	 * @return float
	 */
	public final function getGrossSum(){
		return $this->getGrossPrice() * $this->getQty();
	}
	
	/**
	 * Gets misc informations of the item
	 * @access public
	 * @final
	 * @var mixed the key of the misc array	 
	 * @return mixed
	 */
	public final function getMisc($key = null) {
		if (is_null($key) || !is_array($this->_misc)){
			return $this->_misc;
		}
		if (isset($this->_misc[$key])){
			return $this->_misc[$key];
		}
		return null;
	}
	
	/**
	 * Gets if the quantity is modifiable or not (variable has to be hard coded)
	 * @access public
	 * @final
	 * @return bool
	 */
	public final function isQtyModifiable(){
		return (bool) $this->_qtyModifiable;
	}
	
	/**
	 * Updates the name of the item
	 * @access public
	 * @var string name of the cart item
	 * @return self
	 */
	public final function setName($string){
		$this->_name = $string;
		return $this;
	}
	
	/**
	 * Updates the price of the item
	 * @access public
	 * @var float price of the cart item
	 * @return self
	 */
	public final function setNetPrice($float){
		$this->_netPrice = abs($float);
		return $this;
	}
	
	/**
	 * Updates the vat of the item
	 * @access public
	 * @var float vat of the cart item
	 * @return self
	 */
	public final function setVat($float){
		$this->_vat = $float;
        if ($this->_vat < 0 || $this->_vat >= 100){
            throw new \Exception("Vat must be between 0 and 100 or 0");
        }
		return $this;
	}
	
	/**
	 * Updates the qty of the item
	 * @access public
	 * @var int quanity of the cart item
	 * @return self
	 */
	public final function setQty($int){
		if ($this->_qtyModifiable){
			$this->_qty = $int;
		}
        return $this;
	}
	
	/**
	 * Updates misc informations of the item
	 * @access public
	 * @var mixed misc data of the cart item
	 * @return string
	 */
	public final function setMisc($mixed){
		$this->_misc = $mixed;
		return $this;
	}


}

?>
